package com.stone.framework.user.service.impl;

import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.stone.framework.core.util.Beans;
import com.stone.framework.core.util.Strings;
import com.stone.framework.message.user.RoleUserPageReqBody;
import com.stone.framework.message.user.RoleUserPageResBody;
import com.stone.framework.message.user.RoleUserReqBody;
import com.stone.framework.user.entity.RoleUser;
import com.stone.framework.user.mapper.RoleUserMapper;
import com.stone.framework.user.service.RoleUserService;
import com.stone.framework.user.service.UserService;

@Service
@Transactional(readOnly = true)
public class RoleUserServiceImpl extends ServiceImpl<BaseMapper<RoleUser>, RoleUser> implements RoleUserService {

    // private static final Logger LOGGER = LoggerFactory.getLogger(RoleUserServiceImpl.class);

    @Autowired
    private RoleUserMapper roleUserMapper;

    @Autowired
    private UserService userService;

    @Override
    public IPage<RoleUserPageResBody> queryPage(RoleUserPageReqBody reqBody, Page<RoleUserPageResBody> page) {
        return roleUserMapper.selectPage(page, this.condition(reqBody));
    }

    @Override
    public List<Long> queryByRoleId(Long roleId) {
        List<RoleUser> list = roleUserMapper.selectList(new QueryWrapper<RoleUser>().eq("role_id", roleId));
        return list.stream().map(RoleUser::getUserId).collect(Collectors.toList());
    }

    @Override
    @Transactional(readOnly = false)
    public void save(List<RoleUserReqBody> list) {
        List<RoleUser> allList =
            roleUserMapper.selectList(new QueryWrapper<RoleUser>().eq("role_id", list.get(0).getRoleId()));
        List<RoleUser> reqList = list.stream().map(reqBody -> {
            RoleUser entity = new RoleUser();
            Beans.copyProperties(reqBody, entity);
            return entity;
        }).collect(Collectors.toList());
        reqList.removeAll(allList);
        saveBatch(reqList);
        List<Long> userIdList = list.stream().map(RoleUserReqBody::getUserId).collect(Collectors.toList());
        CompletableFuture.runAsync(() -> this.userService.refresh(userIdList));
    }

    @Override
    @Transactional(readOnly = false)
    // @CacheEvict(value = UserConstant.TOKEN_INFO, key = "#reqBody.username")
    public void delete(List<RoleUserReqBody> list) {
        List<Long> idList = list.stream().map(RoleUserReqBody::getId).collect(Collectors.toList());
        roleUserMapper.deleteBatchIds(idList);
        List<Long> userIdList = list.stream().map(RoleUserReqBody::getUserId).collect(Collectors.toList());
        CompletableFuture.runAsync(() -> this.userService.refresh(userIdList));
    }

    private QueryWrapper<RoleUserPageReqBody> condition(RoleUserPageReqBody condition) {
        QueryWrapper<RoleUserPageReqBody> wrapper = new QueryWrapper<>();
        wrapper.eq("sru.role_id", condition.getRoleId());
        wrapper.eq(Strings.notEmpty(condition.getUsername()), "su.name", condition.getUsername());
        return wrapper;
    }

}
